home *** CD-ROM | disk | FTP | other *** search
/ ETO Development Tools 4 / ETO Development Tools 4.iso / Tools - Objects / MacApp / MacApp 3.0a2 / Libraries / UTECommands.cp < prev    next >
Encoding:
Text File  |  1991-05-01  |  33.4 KB  |  1,225 lines  |  [TEXT/MPS ]

  1. // UTECommands.cp
  2. // Copyright © 1984-1991 Apple Computer Inc. All rights reserved.
  3.  
  4. #ifndef __STDIO__
  5. #include <StdIo.h>
  6. #endif
  7.  
  8. #ifndef __UGEOMETRY__
  9. #include <UGeometry.h>
  10. #endif
  11.  
  12. #ifndef __ULIST__
  13. #include <UList.h>
  14. #endif
  15.  
  16. #ifndef __ALIASES__
  17. #include <Aliases.h>
  18. #endif
  19.  
  20. #ifndef __UFILE__
  21. #include <UFile.h>
  22. #endif
  23.  
  24. #ifndef __EDITIONS__
  25. #include <Editions.h>
  26. #endif
  27.  
  28. #ifndef __DIALOGS__
  29. #include <Dialogs.h>
  30. #endif
  31.  
  32. #ifndef __UAPPLICATION__
  33. #include <UApplication.h>
  34. #endif
  35.  
  36. #ifndef __UDOCUMENT__
  37. #include <UDocument.h>
  38. #endif
  39.  
  40. #ifndef __USCROLLER__
  41. #include <UScroller.h>
  42. #endif
  43.  
  44. #ifndef __SCRAP__
  45. #include <Scrap.h>
  46. #endif
  47.  
  48. #ifndef __UCLIPBOARDMGR__
  49. #include <UClipboardMgr.h>
  50. #endif
  51.  
  52. #ifndef __UPRINTHANDLER__
  53. #include <UPrintHandler.h>
  54. #endif
  55.  
  56. #ifndef __UFAILURE__
  57. #include <UFailure.h>
  58. #endif
  59.  
  60. #ifndef __UMACAPPUTILITIES__
  61. #include <UMacAppUtilities.h>
  62. #endif
  63.  
  64. #ifndef __UPATCH__
  65. #include <UPatch.h>
  66. #endif
  67.  
  68. #ifndef __UMEMORY__
  69. #include <UMemory.h>
  70. #endif
  71.  
  72. #ifndef __UMACAPPGLOBALS__
  73. #include <UMacAppGlobals.h>
  74. #endif
  75.  
  76. #ifndef __UERRORMGR__
  77. #include <UErrorMgr.h>
  78. #endif
  79.  
  80. #ifndef __MENUS__
  81. #include <Menus.h>
  82. #endif
  83.  
  84. #ifndef __UMENUMGR__
  85. #include <UMenuMgr.h>
  86. #endif
  87.  
  88. #ifndef __ERRORS__
  89. #include <Errors.h>
  90. #endif
  91.  
  92. #ifndef __TOOLUTILS__
  93. #include <ToolUtils.h>
  94. #endif
  95.  
  96. #ifndef __PACKAGES__
  97. #include <Packages.h>
  98. #endif
  99.  
  100. #ifndef __FONTS__
  101. #include <Fonts.h>
  102. #endif
  103.  
  104. #ifndef __SCRIPT__
  105. #include <Script.h>
  106. #endif
  107.  
  108. #ifndef __GESTALTEQU__
  109. #include <GestaltEqu.h>
  110. #endif
  111.  
  112. #include "UTECommands.h"
  113.  
  114. //--------------------------------------------------------------------------------------------------
  115. #pragma segment TEFields
  116.  
  117. pascal void DumpTTECommand(TTECommand* theTTECommand)
  118. {
  119.     long oldStyleSize;
  120.     long newStyleSize;
  121.     long last;
  122.  
  123.     fprintf(stderr, "old start/end, new start/end, diff :%1d/%1d,  %1d/%1d,  %1d \n",
  124.             theTTECommand->fOldStart, theTTECommand->fOldEnd,
  125.             theTTECommand->fNewStart, theTTECommand->fNewEnd,
  126.             Max(Max(theTTECommand->fOldEnd - theTTECommand->fOldStart, 0),
  127.             Max(theTTECommand->fNewEnd - theTTECommand->fNewStart, 0)));
  128.     fprintf(stderr, "fTextPad :%1d\n", theTTECommand->fTextPad);
  129.     fprintf(stderr, "fPadding size :%1d\n", GetHandleSize(theTTECommand->fPadding));
  130.  
  131.     oldStyleSize = 0;
  132.     newStyleSize = 0;
  133.     fprintf(stderr, "** Old styles:\n");
  134.     if (theTTECommand->fOldStyles == NULL)
  135.         fprintf(stderr, "NONE!\n");
  136.     else
  137.     {
  138.  
  139.         last = (**(theTTECommand->fOldStyles)).scrpNStyles;
  140.         fprintf(stderr, "Number of table entries: %1d\n", last);
  141.         for (long i = 0; i <= last - 1; ++i)
  142.         {
  143.             ScrpSTElement & theScrpSTElement = (**(theTTECommand->fOldStyles)).scrpStyleTab[i];
  144.  
  145.             fprintf(stderr, "%1d, ofs:%1d ", theScrpSTElement.scrpStartChar);
  146.             //!!! WrLblField(AtStr(''), &scrpFont, bStyle);
  147.             fprintf(stderr, "\n");
  148.         }
  149.         oldStyleSize = GetHandleSize((Handle)(theTTECommand->fOldStyles));
  150.     }
  151.  
  152.     fprintf(stderr, "** New styles:\n");
  153.     if (theTTECommand->fNewStyles == NULL)
  154.         fprintf(stderr, "NONE!\n");
  155.     else
  156.     {
  157.         last = (**(theTTECommand->fNewStyles)).scrpNStyles;
  158.         fprintf(stderr, "Number of table entries: %1d\n", last);
  159.         for (long i = 0; i <= last - 1; ++i)
  160.         {
  161.             ScrpSTElement & theScrpSTElement = (**(theTTECommand->fNewStyles)).scrpStyleTab[i];
  162.  
  163.             fprintf(stderr, "%1d, ofs:%1d ", theScrpSTElement.scrpStartChar);
  164.             //!!! WrLblField(AtStr(''), &scrpFont, bStyle);
  165.             fprintf(stderr, "\n");
  166.         }
  167.         newStyleSize = GetHandleSize((Handle)(theTTECommand->fNewStyles));
  168.     }
  169.  
  170.     fprintf(stderr, "Styles size diff: %1d\n", Max(newStyleSize, oldStyleSize));
  171.     fprintf(stderr, "fStylePad :%1d\n", theTTECommand->fStylePad);
  172. }
  173.  
  174. //--------------------------------------------------------------------------------------------------
  175. #pragma segment TESelCommand
  176. pascal void TTECommand::Initialize(void)        // override 
  177. {
  178.     inherited::Initialize();
  179.  
  180.     fHTE = NULL;
  181.     fNewEnd = 0;
  182.     fNewStart = 0;
  183.     fNewStyles = NULL;
  184.     fNewText = NULL;
  185.     fOldEnd = 0;
  186.     fOldStart = 0;
  187.     fOldStyles = NULL;
  188.     fOldText = NULL;
  189.     fPadding = NULL;
  190.     fStylePad = 0;
  191.     fTEView = NULL;
  192.     fTextPad = 0;
  193. }
  194.  
  195. //--------------------------------------------------------------------------------------------------
  196. #pragma segment TESelCommand
  197.  
  198. pascal void TTECommand::ITECommand(TTEView* itsTEView,
  199.                                    CmdNumber itsCmdNumber,
  200.                                    Boolean itsSaveText)
  201. {
  202.     short selChars;
  203.     Handle h;
  204.     FailInfo fi;
  205.  
  206.     this->ICommand(itsCmdNumber, itsTEView->fDocument, itsTEView);
  207.     fTEView = itsTEView;
  208.     fHTE = itsTEView->fHTE;
  209.  
  210.     {
  211.         TERec & theTERec = **fHTE;
  212.  
  213.         fOldStart = theTERec.selStart;
  214.         fOldEnd = theTERec.selEnd;
  215.         selChars = theTERec.selEnd - theTERec.selStart;
  216.     }
  217.  
  218.     if (fi.Try())
  219.     {
  220.         if (itsSaveText)
  221.         {
  222.             h = NewPermHandle(selChars);
  223.  
  224.             if (selChars > 0)
  225.                 BlockMove((Ptr)((*((**fHTE).hText)) + fOldStart), (*h), selChars);
  226.  
  227.             fOldText = h;
  228.             fTextPad = fOldStart - fOldEnd;
  229.             fPadding = NewPermHandle(0);
  230.         }
  231.  
  232.         /* TextEdit has this "feature" which it exercises if it runs out of memory.  It's
  233.           called DS number 25.  We'll try to avoid it by assuring that enough memory exists
  234.           to fulfill the request, but we won't die because of it.  This is a particularly
  235.           ugly situation - there could be >600K of style information associated with a 32K
  236.           block of text.  And to support undo, we've got to assume that there may momentarily
  237.           be THREE copies floating around, adding up to a total potential liability of almost
  238.           2 Meg for a single TE record.  The worst that can happen, though, is that the text
  239.           will be safe, but it won't have any styles associated with it. */
  240.  
  241.         if ((itsTEView->fStyleType == kWithStyle) && itsTEView->SpaceForStyles((**fHTE).selStart, (**fHTE).selEnd))
  242.         {
  243.             fOldStyles = GetStylScrap(fHTE);
  244.             FailNIL(fOldStyles);
  245.             fStylePad = GetHandleSize((Handle)fOldStyles);
  246.         }
  247.  
  248.         fi.Success();
  249.     }
  250.     else    // Recover
  251.     {
  252.         this->Free();
  253.         fi.ReSignal();
  254.     }
  255. }
  256.  
  257. //--------------------------------------------------------------------------------------------------
  258. #pragma segment TEDoCommand
  259.  
  260. pascal void TTECommand::Free(void)                // override 
  261. {
  262.     fOldText = DisposeIfHandle(fOldText);
  263.     fOldStyles = (StScrpHandle)DisposeIfHandle((Handle)fOldStyles);
  264.     fNewText = DisposeIfHandle(fNewText);
  265.     fNewStyles = (StScrpHandle)DisposeIfHandle((Handle)fNewStyles);
  266.     fPadding = DisposeIfHandle(fPadding);
  267.  
  268.     inherited::Free();
  269. }
  270.  
  271. //--------------------------------------------------------------------------------------------------
  272. #pragma segment TEDoCommand
  273.  
  274. pascal void TTECommand::BanishOldText(void)
  275. {
  276.     if (fOldEnd > fOldStart)
  277.         TEDelete(fHTE);
  278.     SetHandleSize(fPadding, Max(-(fTextPad + fStylePad), 0));
  279.     FailMemError();
  280. }
  281.  
  282. //--------------------------------------------------------------------------------------------------
  283. #pragma segment TEDoCommand
  284.  
  285. pascal void TTECommand::InstallNewText(void)
  286. {
  287.     long savedSize;
  288.     Handle itsText;
  289.     SignedByte savedState;
  290.  
  291.  
  292.     if (fNewEnd > fNewStart)
  293.     {
  294.         itsText = fTEView->fText;
  295.         savedSize = GetHandleSize(itsText);
  296.  
  297. #if qDebug
  298.         if (fNewText == NULL)
  299.             ProgramBreak("InstallNewText called with fNewText == NULL!");
  300. #endif
  301.  
  302.         savedState = LockHandleHigh(fNewText);    // Prevent heap fragmentation for TEInsert 
  303.  
  304.         if (fTEView->fStyleType == kWithStyle)    // If record has style, use it 
  305.             TEStylInsert((*fNewText),            // It's okay for fNewStyles to be NULL here 
  306.                          GetHandleSize(fNewText), fNewStyles, fHTE);
  307.         else                                    // Otherwise, do it the old-fashioned way 
  308.             TEInsert((*fNewText), GetHandleSize(fNewText), fHTE);
  309.  
  310.         HSetState(fNewText, savedState);
  311.  
  312.         if (GetHandleSize(itsText) <= savedSize)
  313.             FailOSErr(memFullErr);
  314.  
  315.         fTEView->fSpecsChanged = TRUE;
  316.     }
  317. }
  318.  
  319. //--------------------------------------------------------------------------------------------------
  320. #pragma segment TEFields
  321.  
  322. pascal void TTECommand::Fields(TObject* obj)    // override 
  323. {
  324.     obj->DoToField("TTECommand", (Ptr)NULL, bClass);
  325.     obj->DoToField("fTEView", (Ptr) & fTEView, bObject);
  326.     obj->DoToField("fHTE", (Ptr) & fHTE, bTEHandle);
  327.     obj->DoToField("fOldStart", (Ptr) & fOldStart, bInteger);
  328.     obj->DoToField("fOldEnd", (Ptr) & fOldEnd, bInteger);
  329.     obj->DoToField("fOldText", (Ptr) & fOldText, bHandle);
  330.     obj->DoToField("fOldStyles", (Ptr) & fOldStyles, bHandle);
  331.     obj->DoToField("fNewStart", (Ptr) & fNewStart, bInteger);
  332.     obj->DoToField("fNewEnd", (Ptr) & fNewEnd, bInteger);
  333.     obj->DoToField("fNewText", (Ptr) & fNewText, bHandle);
  334.     obj->DoToField("fNewStyles", (Ptr) & fNewStyles, bHandle);
  335.     obj->DoToField("fPadding", (Ptr) & fPadding, bHandle);
  336.     obj->DoToField("fTextPad", (Ptr) & fTextPad, bInteger);
  337.     obj->DoToField("fStylePad", (Ptr) & fStylePad, bLongInt);
  338.  
  339.     inherited::Fields(obj);
  340. }
  341.  
  342. //--------------------------------------------------------------------------------------------------
  343. #pragma segment TEDoCommand
  344.  
  345. pascal void TTECommand::RemoveAdditions(void)
  346. {
  347.     if (fNewText != NULL)
  348.     {
  349.         TESetSelect(fNewStart, fNewEnd, fHTE);
  350.         TEDelete(fHTE);
  351.     }
  352.     SetHandleSize(fPadding, Max(fTextPad + fStylePad, 0));
  353.     FailMemError();
  354. }
  355.  
  356. //--------------------------------------------------------------------------------------------------
  357. #pragma segment TEDoCommand
  358.  
  359. pascal void TTECommand::RestoreSelection(void)
  360. {
  361.     TESetSelect(fOldStart, fOldEnd, fHTE);
  362. }
  363.  
  364. //--------------------------------------------------------------------------------------------------
  365. #pragma segment TEDoCommand
  366.  
  367. pascal void TTECommand::ReviveDeletions(void)
  368. {
  369.     Handle itsText;
  370.     long savedSize;
  371.     short nChars;
  372.     SignedByte savedState;
  373.  
  374.  
  375.     TESetSelect(fOldStart, fOldStart, fHTE);    // so insert will take place at right point 
  376.     nChars = (short)GetHandleSize(fOldText);    //!!! long->short
  377.     if (nChars > 0)
  378.     {
  379.         itsText = fTEView->fText;
  380.         savedSize = GetHandleSize(itsText);
  381.  
  382.         savedState = LockHandleHigh(fOldText);    // Prevent heap fragmentation 
  383.  
  384.         if (fTEView->fStyleType == kWithStyle)    // If record has style, use it 
  385.             TEStylInsert((*fOldText), nChars,    // It's okay for fOldStyles to be NULL here 
  386.                          fOldStyles, fHTE);
  387.         else                                    // Otherwise, do it the old-fashioned way 
  388.             TEInsert((*fOldText), nChars, fHTE);
  389.  
  390.         HSetState(fOldText, savedState);
  391.  
  392.         if (GetHandleSize(itsText) <= savedSize)
  393.             FailOSErr(memFullErr);
  394.  
  395.         fTEView->fSpecsChanged = TRUE;
  396.     }
  397. }
  398.  
  399. //--------------------------------------------------------------------------------------------------
  400. #pragma segment TEDoCommand
  401.  
  402. pascal void TTECommand::DoMainFunction(void)
  403. {
  404.     if (fID != cCopy)
  405.         this->BanishOldText();
  406.     this->InstallNewText();
  407.     if (fID != cCopy)
  408.         fTEView->SynchView(kRedraw);
  409. }
  410.  
  411. //--------------------------------------------------------------------------------------------------
  412. #pragma segment TEDoCommand
  413.  
  414. pascal void TTECommand::DoIt(void)                // override 
  415. {
  416.     fTEView->Focus();                            //??? What if Focus fails
  417.  
  418.     this->DoMainFunction();
  419. #if qDebug
  420.     if (pTEIntenseDebugging)
  421.         DumpTTECommand(this);
  422. #endif
  423.  
  424. }
  425.  
  426. //--------------------------------------------------------------------------------------------------
  427. #pragma segment TEDoCommand
  428.  
  429. pascal void TTECommand::UndoIt(void)            // override 
  430. {
  431.     fTEView->Focus();                            //??? What if Focus fails
  432.  
  433.     this->RemoveAdditions();
  434.     this->ReviveDeletions();
  435.     this->RestoreSelection();
  436.     if (fID != cCopy)
  437.         fTEView->SynchView(kRedraw);
  438. #if qDebug
  439.     if (pTEIntenseDebugging)
  440.         DumpTTECommand(this);
  441. #endif
  442.  
  443. }
  444.  
  445. //--------------------------------------------------------------------------------------------------
  446. #pragma segment TEDoCommand
  447.  
  448. pascal void TTECommand::RedoIt(void)            // override 
  449. {
  450.     fTEView->Focus();                            //??? What if Focus fails
  451.  
  452.     this->RestoreSelection();
  453.     this->DoMainFunction();
  454. #if qDebug
  455.     if (pTEIntenseDebugging)
  456.         DumpTTECommand(this);
  457. #endif
  458.  
  459. }
  460.  
  461. //--------------------------------------------------------------------------------------------------
  462. #pragma segment TESelCommand
  463.  
  464. pascal void TTECutCopyCommand::ITECutCopyCommand(TTEView* itsTEView,
  465.                                                  CmdNumber itsCmdNumber)
  466. {
  467.     fClipCreated = FALSE;
  468.     this->ITECommand(itsTEView, itsCmdNumber, TRUE);
  469.     fChangesClipboard = TRUE;
  470.     fCausesChange = (itsCmdNumber != cCopy);
  471. }
  472.  
  473. //--------------------------------------------------------------------------------------------------
  474. #pragma segment TEDoCommand
  475.  
  476. pascal void TTECutCopyCommand::Free(void)        // override 
  477. {
  478.     if (fClipCreated)
  479.         fOldText = NULL;
  480.     inherited::Free();
  481. }
  482.  
  483. //--------------------------------------------------------------------------------------------------
  484. #pragma segment TEDoCommand
  485.  
  486. pascal void TTECutCopyCommand::DoIt(void)        // override 
  487. {
  488.     //TTECutCopyCommand.DoIt
  489.     TTEView * clipTEView;
  490.     FailInfo fi;
  491.     TextStyle clipStyle;
  492.     VPoint itsSize;
  493.     VRect itsMargins;
  494.  
  495.     VOLATILE(clipTEView);
  496.  
  497.     fTEView->Focus();                            //??? What if Focus fails
  498.  
  499.     SetTextStyle(clipStyle, applFont, 0, 12, gRGBBlack);// Initial style same as virgin TEView 
  500.  
  501.     itsSize = VPoint(50, 100);                    // An arbitrary initial size.
  502.     itsMargins = VRect(8, 10, 0, 10);            // No bottom margin.
  503.  
  504.     clipTEView = new TTEView;                    // Create a new view for the clipboard 
  505.     clipTEView->ITEView(NULL, NULL,                // Initialize view 
  506.                         gZeroVPt, itsSize, sizeSuperView, sizeVariable, itsMargins, clipStyle, teFlushDefault, fTEView->fStyleType, fTEView->fAutoWrap);
  507.     clipTEView->fAcceptsChanges = FALSE;        // This is a read-only view 
  508.  
  509.     // Cut can eat into temp memory so users can rescue text from overweight documents     
  510.     if (fi.Try())
  511.     {
  512.         if (!fCausesChange)                        // If Copy-ing, assure there's enough room 
  513.             FailSpaceIsLow();
  514.         fi.Success();
  515.     }
  516.     else    // Recover
  517.     {
  518.         clipTEView = (TTEView *)(FreeIfObject(clipTEView));
  519.         fi.ReSignal();
  520.     }
  521.  
  522.     clipTEView->StuffText(fOldText);
  523.     FailSpaceIsLow();
  524.  
  525.     //??? GOT TO FIGURE OUT SOME WAY TO PRE-FLIGHT THIS! ??????????????????????????????????? 
  526.     if (clipTEView->fStyleType == kWithStyle)    // If record has style 
  527.         SetStylScrap(0, MAXINT, fOldStyles,        // …then put in the styles 
  528.                      kDontRedraw, clipTEView->fHTE);
  529.     FailSpaceIsLow();
  530.  
  531.     clipTEView->fFreeText = TRUE;                // Let TEView know it has to free the text 
  532.  
  533.     gClipboardMgr->ClaimClipboard(clipTEView);    // Okay to claim (will call RecalcText!) 
  534.  
  535.     fClipCreated = TRUE;                        // We be done 
  536.     this->DoMainFunction();                        // Do the actual cut/copy 
  537.  
  538. #if qDebug
  539.     if (pTEIntenseDebugging)
  540.     {
  541.         DumpTERecord(clipTEView->fHTE);
  542.         DumpTTECommand(this);
  543.     }
  544. #endif
  545.  
  546. }
  547.  
  548. //--------------------------------------------------------------------------------------------------
  549. #pragma segment TEDoCommand
  550.  
  551. pascal void TTECutCopyCommand::ReviveDeletions(void)// override 
  552. {
  553.     if (fID == cCut)
  554.         inherited::ReviveDeletions();            // Don't do it for COPY 
  555. }
  556.  
  557. //--------------------------------------------------------------------------------------------------
  558. #pragma segment TEFields
  559.  
  560. pascal void TTECutCopyCommand::Fields(TObject* obj)// override 
  561. {
  562.     obj->DoToField("TTECutCopyCommand", (Ptr)NULL, bClass);
  563.     obj->DoToField("fClipCreated", (Ptr) & fClipCreated, bBoolean);
  564.  
  565.     inherited::Fields(obj);
  566. }
  567.  
  568. //--------------------------------------------------------------------------------------------------
  569. #pragma segment TESelCommand
  570.  
  571. pascal void TTEPasteCommand::ITEPasteCommand(TTEView* itsTEView)
  572. /* We can't use TEPaste because it clobbers the DeskScrap; the text would be recoverable
  573.   from the special TextEdit Scrap, but other types of non-TEXT scrap are permanently
  574.   lost, it seems */
  575.  
  576. {
  577.     Boolean savedPerm;
  578.     short newLength;
  579.     long newStyleLen;
  580.     Handle newText;
  581.     StScrpHandle newStyles;
  582.     ResType dataType = '%%%%';
  583.     FailInfo fi;
  584.  
  585.     VOLATILE(newText);
  586.     VOLATILE(newStyles);
  587.  
  588.     this->ITECommand(itsTEView, cPaste, TRUE);    // Perform stock initializations 
  589.  
  590.     savedPerm = FALSE;
  591.  
  592.     newStyleLen = 0;                            // Assume there are no new styles 
  593.     newStyles = NULL;
  594.     newText = NULL;
  595.  
  596.     if (fi.Try())
  597.     {
  598.         newText = NewPermHandle(0);                // Create handle to receive clipboard data 
  599.         if (itsTEView->fStyleType == kWithStyle)
  600.         {
  601.             newStyles = StScrpHandle(NewPermHandle(0));// Same for handle to receive style info 
  602.         }
  603.  
  604.         //!!! dataType is not used by GetDataToPaste.  should it really be parameter?
  605.         newLength = (short)gClipboardMgr->GetDataToPaste(newText, dataType);//!!! long->short
  606.  
  607.         if (newLength > 0)
  608.         {
  609. #if qDebug
  610.             if (dataType != 'TEXT')
  611.                 ProgramBreak("TEPasteCommand given some non-text from clipboard");
  612.             else
  613. #endif
  614.  
  615.             {                                // Prime "new" values 
  616.                 fNewText = newText;
  617.                 fNewStart = (**fHTE).selStart;
  618.                 fNewEnd = fNewStart + newLength;
  619.                 fTextPad = newLength - (fOldEnd - fOldStart);
  620.  
  621.                 if (itsTEView->fStyleType == kWithStyle)
  622.                 {
  623.                     newStyleLen = gClipboardMgr->fClipView->GivePasteData(Handle(newStyles), 'styl');
  624.                     if (newStyleLen > 0)
  625.                     {
  626.                         fNewStyles = newStyles;
  627.                         fStylePad =                // Difference between old and new styles 
  628.                                    newStyleLen - fStylePad;
  629.                     }
  630.                     else
  631.                         newStyles = (StScrpHandle)DisposeIfHandle((Handle)newStyles);
  632.                 }
  633.  
  634.                 SetPermHandleSize(fPadding, Max(fTextPad + fStylePad, 0));
  635.  
  636.                 FailSpaceIsLow();
  637.             }
  638.         }
  639.         else
  640.         {
  641.             newText = DisposeIfHandle(newText);
  642.             newStyles = (StScrpHandle)DisposeIfHandle((Handle)newStyles);
  643.         }
  644.         fi.Success();
  645.     }
  646.     else    // Recover
  647.     {
  648.         if (newText != fNewText)                // newText is assigned to fNewText 
  649.             newText = DisposeIfHandle(newText);    // …so avoid disposing twice. 
  650.         if (newStyles != fNewStyles)            // Ditto for newStyles. 
  651.             newStyles = (StScrpHandle)DisposeIfHandle((Handle)newStyles);
  652.         this->Free();
  653.     }
  654. }
  655.  
  656. //--------------------------------------------------------------------------------------------------
  657. #pragma segment TEFields
  658.  
  659. pascal void TTEPasteCommand::Fields(TObject* obj)// override 
  660. {
  661.     obj->DoToField("TTEPasteCommand", (Ptr)NULL, bClass);
  662.  
  663.     inherited::Fields(obj);
  664. }
  665.  
  666. //--------------------------------------------------------------------------------------------------
  667. #pragma segment TESelCommand
  668.  
  669. pascal void TTEStyleCommand::ITEStyleCommand(TTEView* itsTEView,
  670.                                              const TextStyle& itsNewStyle,
  671.                                              CmdNumber itsCmdNumber,
  672.                                              short itsMode)
  673. {
  674.     FailInfo fi;
  675.  
  676.     this->ITECommand(itsTEView, itsCmdNumber, FALSE);// Perform stock initialization, sans text 
  677.  
  678.     fOldTextStyle = itsTEView->fTextStyle;
  679.     fNewTextStyle = itsNewStyle;
  680.  
  681.     // Only do color change if we can 
  682.     if (qNeedsColorQD || gConfiguration.hasColorQD)
  683.         fMode = itsMode;
  684.     else
  685.         fMode = itsMode &~doColor;
  686. }
  687.  
  688. //--------------------------------------------------------------------------------------------------
  689. #pragma segment TEDoCommand
  690.  
  691. pascal void TTEStyleCommand::InstallOneStyle(const TextStyle& newStyl)
  692. {
  693.     fTEView->SetOneStyle(fOldStart, fOldEnd, fMode, newStyl, kRedraw);// Focus'es for us 
  694. }
  695.  
  696. //--------------------------------------------------------------------------------------------------
  697. #pragma segment TEDoCommand
  698.  
  699. pascal void TTEStyleCommand::InstallManyStyles(StScrpHandle newStyls)
  700. {
  701.     fTEView->Focus();
  702.     // No need to check for fStyleType, since we only get here if the record is stylish 
  703.     SetStylScrap(fOldStart, fOldEnd, newStyls, kRedraw, fHTE);
  704.     fTEView->RecalcText();                        // Might have changed number of lines 
  705.     fTEView->SynchView(kRedraw);                // Show corrected view 
  706.  
  707.     fTEView->fSpecsChanged = TRUE;
  708. }
  709.  
  710. //--------------------------------------------------------------------------------------------------
  711. #pragma segment TEDoCommand
  712.  
  713. pascal void TTEStyleCommand::DoIt(void)            // override 
  714. {
  715.     TextStyle aTextStyle;
  716.  
  717.     aTextStyle = fNewTextStyle;
  718.     this->InstallOneStyle(aTextStyle);
  719.     fMode = fMode &~doToggle;                    //    fMode = BAND(fMode, BNOT(doToggle));// Turn off toggle mode, if set 
  720. #if qDebug
  721.     if (pTEIntenseDebugging)
  722.         DumpTTECommand(this);
  723. #endif
  724.  
  725. }
  726.  
  727. //--------------------------------------------------------------------------------------------------
  728. #pragma segment TEDoCommand
  729.  
  730. pascal void TTEStyleCommand::UndoIt(void)        // override 
  731. {
  732.     TextStyle aTextStyle;
  733.  
  734.     this->RestoreSelection();
  735.  
  736.     if (fTEView->fStyleType == kWithoutStyle)
  737.     {
  738.         aTextStyle = fOldTextStyle;
  739.         this->InstallOneStyle(aTextStyle);
  740.     }
  741.     else
  742.         this->InstallManyStyles(fOldStyles);
  743. #if qDebug
  744.     if (pTEIntenseDebugging)
  745.         DumpTTECommand(this);
  746. #endif
  747.  
  748. }
  749.  
  750. //--------------------------------------------------------------------------------------------------
  751. #pragma segment TEDoCommand
  752.  
  753. pascal void TTEStyleCommand::RedoIt(void)        // override 
  754. {
  755.     this->RestoreSelection();
  756.     this->DoIt();
  757. }
  758.  
  759. //--------------------------------------------------------------------------------------------------
  760. #pragma segment TEFields
  761.  
  762. pascal void TTEStyleCommand::Fields(TObject* obj)// override 
  763. {
  764.     obj->DoToField("TTEStyleCommand", (Ptr)NULL, bClass);
  765.     obj->DoToField("fMode", (Ptr) & fMode, bInteger);
  766.     obj->DoToField("fOldTextStyle", (Ptr) & fOldTextStyle, bTextStyle);
  767.     obj->DoToField("fNewTextStyle", (Ptr) & fNewTextStyle, bTextStyle);
  768.  
  769.     inherited::Fields(obj);
  770. }
  771.  
  772. //--------------------------------------------------------------------------------------------------
  773. #pragma segment TERes
  774.  
  775. pascal void TTETypingCommand::ITETypingCommand(TTEView* itsTEView,
  776.                                                short itsFirstChar)
  777. {
  778.     FailInfo fi;
  779.  
  780.     this->ITECommand(itsTEView, cTyping, TRUE);
  781.  
  782.     if (fi.Try())
  783.     {
  784.  
  785.         fNewStart = (**fHTE).selStart;            // Start and end are the same 
  786.         fNewEnd = fNewStart;
  787.  
  788.         fNewText = NULL;
  789.         fNewText = NewPermHandle(0);            // Allocate an empty block for text 
  790.  
  791.         fCompleted = FALSE;                        // We've only just begun… 
  792.         fFirstChar = itsFirstChar;                // Save character for Doit 
  793.         fi.Success();
  794.     }
  795.     else    // Recover
  796.     {
  797.         this->Free();
  798.         fi.ReSignal();
  799.     }
  800. }
  801.  
  802. //--------------------------------------------------------------------------------------------------
  803. #pragma segment TERes
  804.  
  805. pascal void TTETypingCommand::Free(void)        // override 
  806. {
  807.     if (fTEView->fTypingCommand == this)
  808.         fTEView->fTypingCommand = NULL;
  809.     inherited::Free();
  810. }
  811.  
  812. //--------------------------------------------------------------------------------------------------
  813. #pragma segment TERes
  814.  
  815. pascal void TTETypingCommand::DoNormalChar(short aChar)
  816. {
  817.     FailOSErr(PtrAndHand((Ptr)((&aChar) + 1),    // Append char to end of fNewText 
  818.                          fNewText, 1));
  819.     ++fNewEnd;                        // Bump both end of "selection" 
  820.     ++fTextPad;                    // …and padding value 
  821.  
  822.     SetHandleSize(fPadding,                        /* This SetHandleSize can't grow the handle,
  823.                                                 */Max(-(fTextPad + fStylePad), 0));// …so it shouldn't fail. 
  824.     FailMemError();
  825. }
  826.  
  827. //--------------------------------------------------------------------------------------------------
  828. #pragma segment TERes
  829.  
  830. //!!!
  831. typedef TextStyle* TSPtr;
  832.  
  833. // User has backspaced to the left of the original starting point. First, copy the
  834. // character (which may be more than one byte long if we are using a non-Roman script) to
  835. // a temporary buffer. The assumption is that no character will ever be longer than four
  836. // bytes. Sorry, folks, MacApp does not support typing in any script with more than 4
  837. // billion characters. Next, copy the character to the front of fOldText, and adjust
  838. // fOldStart, fNewStart, and fNewEnd. Note that we do !check for MemSpaceIsLow, since we
  839. // want to let the user delete characters.
  840. pascal void TTETypingCommand::BkSpcLeft(Handle theText,
  841.                                         short curStart)
  842. {
  843.     short savedSize;
  844.     short theHeight;
  845.     short theAscent;
  846.     long oldSize;
  847.     TSPtr aTextStyle;
  848.     char savedChar[4];    //Pascal: savedChar:    PACKED ARRAY [0..3] OF Char;
  849.     TextStyle delStyle;
  850.  
  851.     savedSize = 1;
  852.     while (CharByte((*theText), curStart - savedSize) > 0)
  853.         ++savedSize;
  854.     curStart -= savedSize;
  855.  
  856. #if qDebug
  857.     if (savedSize > 4)
  858.         ProgramBreak("Character > 4 bytes");
  859. #endif
  860.  
  861.     if (savedSize == 1)                            /* Slight speed optimization for normal case
  862.                                                 */
  863.         savedChar[0] = (*((CharsHandle)theText))[curStart];
  864.     else
  865.         BlockMove((Ptr)((*theText) + curStart), (Ptr)savedChar, savedSize);
  866.  
  867.     if (fTEView->fStyleType == kWithStyle)        // Only do this if styles are around 
  868.     {
  869.         TEGetStyle(curStart, delStyle,            // Get the style of the deleted character 
  870.                    theHeight, theAscent, fHTE);    // (1 or 4 bytes, it's all only one style) 
  871.  
  872.         if (!EqualBlocks((Ptr) & delStyle,        // If style doesn't match first in the list 
  873.                          (Ptr) & ((**fOldStyles).scrpStyleTab[0].scrpFont), sizeof(TextStyle)))
  874.         {
  875.             // …then insert new style at head of list 
  876.             fTEView->fSpecsChanged = TRUE;        // User backspaced into new style! 
  877.  
  878.             oldSize =                            // Make room for the new style element 
  879.                      GetHandleSize(Handle(fOldStyles));
  880.             SetHandleSize(Handle(fOldStyles), oldSize + sizeof(ScrpSTElement));
  881.             FailMemError();
  882.             fStylePad += sizeof(ScrpSTElement);
  883.  
  884.             {
  885.                 ScrpSTElement & theScrpSTElement = (**fOldStyles).scrpStyleTab[0];
  886.  
  887.                 BlockMove((Ptr) & (theScrpSTElement.scrpStartChar),// Move entire array up one element's size 
  888.                       (Ptr)(&(theScrpSTElement.scrpStartChar) + sizeof(ScrpSTElement)), oldSize - sizeof((**fOldStyles).scrpNStyles));
  889.             }
  890.  
  891.             (**fOldStyles).scrpNStyles++;// One more style 
  892.  
  893.             {
  894.                 ScrpSTElement & theScrpSTElement = (**fOldStyles).scrpStyleTab[0];
  895.  
  896.                 theScrpSTElement.scrpHeight = theHeight;// Fill in the blanks 
  897.                 theScrpSTElement.scrpAscent = theAscent;
  898.                 aTextStyle = (TSPtr)(&theScrpSTElement.scrpFont);
  899.                 (*aTextStyle) = delStyle;
  900.             }
  901.         }
  902.  
  903.         (**fOldStyles).scrpStyleTab[0].scrpStartChar--;// Regardless, back off offset by one 
  904.     }
  905.  
  906.     SetHandleSize(fPadding, GetHandleSize(fOldText) + savedSize + fStylePad);
  907.     FailMemError();
  908.     Munger(fOldText, 0, NULL, 0, (Ptr)savedChar, savedSize);
  909.     FailMemError();
  910.     fOldStart = curStart;                        // Treat this as though original selection 
  911.     fNewStart = curStart;                        // …had included this character 
  912.     fNewEnd = curStart;
  913.     fTextPad -= savedSize;
  914. }
  915.  
  916. //--------------------------------------------------------------------------------------------------
  917. #pragma segment TERes
  918.  
  919. pascal void TTETypingCommand::BkSpcRight(Handle theText,
  920.                                          short curStart)
  921. {
  922.     short savedSize;
  923.  
  924.  
  925.     savedSize = 1;
  926.     while (CharByte((*theText), curStart - savedSize) > 0)
  927.         ++savedSize;
  928.     SetHandleSize(fPadding, Max(-(fTextPad - savedSize + fStylePad), 0));
  929.     FailMemError();
  930.     fNewEnd -= savedSize;
  931.     fTextPad -= savedSize;
  932.  
  933.     SetHandleSize(fNewText, fNewEnd - fNewStart);/* Shouldn't fail as we're only shrinking it
  934.                                                 */
  935.     FailMemError();
  936. }
  937.  
  938. //--------------------------------------------------------------------------------------------------
  939. // Forward delete courtesy of: Larry Goldman.  Used by permission. 
  940. #pragma segment TERes
  941.  
  942. pascal void TTETypingCommand::FwdDelete(Handle theText,
  943.                                         short curStart,
  944.                                         short curEnd)
  945. {
  946.     short savedSize;
  947.     short theHeight;
  948.     short theAscent;
  949.     long oldSize;
  950.     TSPtr aTextStyle;
  951.     char savedChar[3];
  952.     TextStyle delStyle;
  953.     long textSize;
  954.     long oldTextSize;
  955.  
  956.     textSize = GetHandleSize(theText);
  957.     if ((curStart == curEnd) && (curStart < textSize))
  958.     {
  959.  
  960.         savedSize = 0;                            //Get the complete character
  961.         while ((curStart + savedSize <= textSize) && (CharByte((*theText), curStart + savedSize) > 0))
  962.             ++savedSize;
  963.         ++savedSize;
  964. #if qDebug
  965.         if (savedSize > 4)
  966.             ProgramBreak("Character > 4 bytes");
  967. #endif
  968.  
  969.         if (savedSize == 1)                        // Slight speed optimization for normal case 
  970.             savedChar[0] = (*((CharsHandle)theText))[curStart];
  971.         else
  972.             BlockMove((Ptr)((*theText) + curStart), (Ptr)savedChar, savedSize);
  973.  
  974.         if ((curStart >= fNewStart) && (curStart < fNewEnd))// char is within fNewText 
  975.         {
  976.             /*Remove the char from fNewText and update
  977.               fNewEnd and fTextPad*/
  978.             SetHandleSize(fPadding, Max(-(fTextPad - savedSize + fStylePad), 0));
  979.             FailMemError();
  980.             fNewEnd -= savedSize;
  981.             fTextPad -= savedSize;
  982.  
  983.             // Shouldn't fail as we're only shrinking it 
  984.             Munger(fNewText, curStart - fNewStart, NULL, savedSize, (Ptr)savedChar, 0);
  985.             FailMemError();
  986.         }
  987.         else                                    /* add char to the end of fOldChars, don't
  988.                                                   update fOldEnd, but update fPadding*/
  989.             {
  990.             oldTextSize = GetHandleSize(fOldText);
  991.             if (fTEView->fStyleType == kWithStyle)// Only do this if styles are around 
  992.             {
  993.                 TEGetStyle(curStart, delStyle,    // Get the style of the deleted character 
  994.                            theHeight, theAscent, fHTE);// (1 or 4 bytes, it's all only one style) 
  995.  
  996.                 if (!EqualBlocks((Ptr) & delStyle,// If style doesn't match last in the list 
  997.                                  (Ptr) & (**fOldStyles).scrpStyleTab[(**fOldStyles).scrpNStyles - 1].scrpFont, sizeof(TextStyle)))
  998.                 {
  999.                     // …then insert new style at end of list 
  1000.                     fTEView->fSpecsChanged = TRUE;// User backspaced into new style! 
  1001.  
  1002.                     oldSize = GetHandleSize((Handle)fOldStyles);// Make room for the new style element 
  1003.                     SetHandleSize((Handle)fOldStyles, oldSize + sizeof(ScrpSTElement));
  1004.                     FailMemError();
  1005.                     fStylePad = fStylePad + sizeof(ScrpSTElement);
  1006.  
  1007.                     (**fOldStyles).scrpNStyles++;// One more style 
  1008.  
  1009.                     {
  1010.                         ScrpSTElement & theScrpSTElement = (**fOldStyles).scrpStyleTab[(**fOldStyles).scrpNStyles - 1];
  1011.  
  1012.                         theScrpSTElement.scrpStartChar = oldTextSize;
  1013.                         theScrpSTElement.scrpHeight = theHeight;// Fill in the blanks 
  1014.                         theScrpSTElement.scrpAscent = theAscent;
  1015.                         aTextStyle = (TSPtr) & theScrpSTElement.scrpFont;
  1016.                         (*aTextStyle) = delStyle;
  1017.                     }
  1018.                 }
  1019.             }
  1020.  
  1021.             SetHandleSize(fPadding, oldTextSize + savedSize + fStylePad);
  1022.             FailMemError();
  1023.             Munger(fOldText, oldTextSize, NULL, 0, (Ptr)savedChar, savedSize);
  1024.             FailMemError();
  1025.             fTextPad = fTextPad - savedSize;
  1026.  
  1027.         }
  1028.     }
  1029. }
  1030.  
  1031. //--------------------------------------------------------------------------------------------------
  1032. /* ??? All this handle munging is expensive.  Better would be to accumulate memory in
  1033.   "chunks" of, say, 16 bytes so that this checking need not happen every time through.
  1034.   Fortunately, the normal cases are not that bad. */
  1035. #pragma segment TERes
  1036.  
  1037. pascal void TTETypingCommand::AddCharacter(short aChar)
  1038. {
  1039.     Handle theText;
  1040.     short curSelStart;
  1041.     short curSelEnd;
  1042.     Boolean savedPerm;
  1043.     FailInfo fi;
  1044.     
  1045.     VOLATILE(savedPerm);
  1046.  
  1047.     fView->Update();                            /* Makes sure that all of TE's actions are
  1048.                                                   Visible */
  1049.     fView->Focus();
  1050.  
  1051.     {
  1052.         TERec & theTERec = **fHTE;
  1053.  
  1054.         curSelStart = theTERec.selStart;
  1055.         curSelEnd = theTERec.selEnd;
  1056.         theText = theTERec.hText;
  1057.     }
  1058.     if (fi.Try())
  1059.     {
  1060.         savedPerm = PermAllocation(TRUE);
  1061.  
  1062.         /* Update the fNewText handle and other information.  Note that because of backspace,
  1063.           this can be tricky.*/
  1064.  
  1065.         if (aChar == chFwdDelete)                // User types forward delete, so keep in  synch
  1066.             this->FwdDelete(theText, curSelStart, curSelEnd);
  1067.  
  1068.         else if (aChar != chBackspace)            // Not a backspace. Do the right thing 
  1069.             this->DoNormalChar(aChar);
  1070.  
  1071.         else if ((curSelStart <= fOldStart) && (curSelStart > 0) && (curSelStart == curSelEnd))// User typed backspace so keep in synch 
  1072.             this->BkSpcLeft(theText, curSelStart);    // Handle backspace to left of start 
  1073.  
  1074.         else if (fNewEnd > fNewStart)            // Delete 1 character from end of fNewText 
  1075.             this->BkSpcRight(theText, curSelStart);    // Handle backspace to right of start 
  1076.  
  1077.         savedPerm = PermAllocation(savedPerm);
  1078.         fi.Success();
  1079.     }
  1080.     else    // Recover
  1081.     {
  1082.         savedPerm = PermAllocation(savedPerm);
  1083.         fi.ReSignal();
  1084.     }
  1085.  
  1086.  
  1087.     if (aChar != chFwdDelete)
  1088.     /* Let TextEdit have the character, as either 1) we're adding a byte, so we know there
  1089.       is a reserve tank, so the worst this will do is eat into it a little, or 2) we're
  1090.       deleting a character, which can only decrease memory usage. */
  1091.         TEKey(aChar, fHTE);
  1092.     else if (curSelStart != curSelEnd)            // forward delete with chars selected
  1093.         TEDelete(fHTE);
  1094.     else if (curSelStart < GetHandleSize(theText))
  1095.     {
  1096.         // forward delete with insertion point
  1097.         TEKey(chRight, fHTE);
  1098.         TEKey(chBackspace, fHTE);
  1099.     }
  1100.  
  1101.     fTEView->SynchView(kRedraw);                // Now clean up the view. 
  1102.  
  1103. #if qDebugMsg
  1104.     if (pTEIntenseDebugging)
  1105.     {
  1106.         WrLblHandleContents("fOldText", fOldText);
  1107.         fprintf(stderr, "\n");
  1108.         WrLblHandleContents("fNewText", fNewText);
  1109.         fprintf(stderr, "\n");
  1110.         DumpTTECommand(this);
  1111.     }
  1112. #endif
  1113.  
  1114. }
  1115.  
  1116. //--------------------------------------------------------------------------------------------------
  1117. #pragma segment TERes
  1118.  
  1119. pascal void TTETypingCommand::DoIt(void)        // override 
  1120.  
  1121. {
  1122.     this->AddCharacter(fFirstChar);
  1123. #if qDebug
  1124.     if (pTEIntenseDebugging)
  1125.         DumpTTECommand(this);
  1126. #endif
  1127.  
  1128. }
  1129.  
  1130. //--------------------------------------------------------------------------------------------------
  1131.  
  1132. #pragma segment TEDoCommand
  1133.  
  1134. pascal void TTETypingCommand::RedoIt(void)        // override 
  1135.  
  1136. {
  1137.     TextStyle currentStyle;
  1138.     short lineHeight;
  1139.     short fontAscent;
  1140.     Boolean resetStyle;
  1141.  
  1142.  
  1143.     if ((fOldEnd - fOldStart) == GetHandleSize(fOldText))
  1144.     {
  1145.         // No chars were vacuumed
  1146.         resetStyle = FALSE;
  1147.         if ((fTEView->fStyleType == kWithStyle) && (fOldEnd == fOldStart))
  1148.         {
  1149.             TEGetStyle(fOldStart, currentStyle, lineHeight, fontAscent, fHTE);
  1150.             resetStyle =!EqualBlocks((Ptr) & currentStyle, (Ptr) & (*fOldStyles)->scrpStyleTab[0].scrpFont, sizeof(TextStyle));
  1151.         }
  1152.  
  1153.         if (resetStyle)                            // The new text has a style of its own 
  1154.             fNewStyles = fOldStyles;            // Make InstallNewText insert styles, too 
  1155.         inherited::RedoIt();
  1156.         if (resetStyle)
  1157.             fNewStyles = NULL;                    // So fNewStyles doesn't get disposed 
  1158.     }
  1159.     else
  1160.     {
  1161.         fTEView->Focus();                        //??? What if Focus fails
  1162.         TESetSelect(fOldStart, fOldStart + GetHandleSize(fOldText), fHTE);/* select vacuumed chars,
  1163.                                                   too */
  1164.         TEDelete(fHTE);                            // Remove old text, including vacuumed chars
  1165.         SetHandleSize(fPadding, Max(-(fTextPad + fStylePad), 0));
  1166.         FailMemError();
  1167.         this->InstallNewText();
  1168.         fTEView->SynchView(kRedraw);
  1169. #if qDebug
  1170.         if (pTEIntenseDebugging)
  1171.             DumpTTECommand(this);
  1172. #endif
  1173.  
  1174.     }
  1175. }
  1176.  
  1177. //--------------------------------------------------------------------------------------------------
  1178. #pragma segment TEDoCommand
  1179.  
  1180. pascal void TTETypingCommand::UndoIt(void)        // override 
  1181. {
  1182.     this->CompleteTyping();
  1183.     inherited::UndoIt();
  1184. }
  1185.  
  1186. //--------------------------------------------------------------------------------------------------
  1187. #pragma segment TERes
  1188.  
  1189. pascal void TTETypingCommand::CompleteTyping(void)
  1190. {
  1191.     long offset;
  1192.  
  1193.  
  1194.     fCompleted = TRUE;
  1195.  
  1196.     if (fTEView->fStyleType == kWithStyle)
  1197.     {
  1198.         StScrpRec & theStScrpRec = **fOldStyles;
  1199.         {
  1200.             offset = -theStScrpRec.scrpStyleTab[0].scrpStartChar;
  1201.             if (offset > 0)
  1202.                 for (short i = 0; i <= theStScrpRec.scrpNStyles - 1; ++i)
  1203.                     theStScrpRec.scrpStyleTab[i].scrpStartChar += offset;
  1204.         }
  1205.     }
  1206. #if qDebug
  1207.     if (pTEIntenseDebugging)
  1208.         DumpTTECommand(this);
  1209. #endif
  1210.  
  1211. }
  1212.  
  1213. //--------------------------------------------------------------------------------------------------
  1214. #pragma segment TEFields
  1215.  
  1216. pascal void TTETypingCommand::Fields(TObject* obj)// override 
  1217. {
  1218.     obj->DoToField("TTETypingCommand", (Ptr)NULL, bClass);
  1219.     obj->DoToField("fCompleted", (Ptr) & fCompleted, bBoolean);
  1220.     obj->DoToField("fFirstChar", (Ptr) & fFirstChar, bBoolean);
  1221.  
  1222.     inherited::Fields(obj);
  1223. }
  1224.  
  1225.